Apply RUSTFLAGS env var to rustc builds
authorBrian Anderson <banderson@mozilla.com>
Wed, 17 Feb 2016 00:48:03 +0000 (00:48 +0000)
committerBrian Anderson <banderson@mozilla.com>
Wed, 16 Mar 2016 16:49:21 +0000 (16:49 +0000)
This passes RUSTFLAGS to rustc builds for the target architecture.

We don't want to pass the RUSTFLAGS args to multiple architectures because
they may contain architecture-specific flags. Ideally, the scheme
we would use would treat plugins and build scripts - which may not
be for the target architecture - consistently. Unfortunately it's
quite difficult in the current Cargo architecture to seperately
identify build scripts, plugins and their dependencies from
code used by the target.

So the scheme here is very simple:

1) If --target is not specified, RUSTFLAGS applies to all builds.
2) If --target is specified, RUSTFLAGS only applies to builds
   with the Kind::Target target kind, which indicates build units
   derived from the requested --target.

Closes #2112

Cargo.lock
src/cargo/ops/cargo_rustc/context.rs
src/cargo/ops/cargo_rustc/mod.rs
tests/test_cargo_compile.rs

index f5e59849d515290c29dcce5f8f7fb112f45374d7..766d10984bfc1218d075b779b398682fdfdc1965 100644 (file)
@@ -19,11 +19,11 @@ dependencies = [
  "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "libgit2-sys 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "num_cpus 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.1.48 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.1.55 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
- "semver 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "tar 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tar 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -43,10 +43,10 @@ dependencies = [
 
 [[package]]
 name = "aho-corasick"
-version = "0.4.1"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "memchr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -64,7 +64,7 @@ name = "cmake"
 version = "0.1.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "gcc 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -98,11 +98,11 @@ name = "curl-sys"
 version = "0.1.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "gcc 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "pkg-config 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -110,7 +110,7 @@ name = "docopt"
 version = "0.6.78"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "regex 0.1.48 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.1.55 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "strsim 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -121,7 +121,7 @@ version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.1.48 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.1.55 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -143,7 +143,7 @@ dependencies = [
 
 [[package]]
 name = "gcc"
-version = "0.3.23"
+version = "0.3.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -186,7 +186,7 @@ name = "hamcrest"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "num 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -209,12 +209,12 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cmake 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "gcc 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "libssh2-sys 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "pkg-config 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -234,7 +234,7 @@ dependencies = [
  "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "pkg-config 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -242,9 +242,9 @@ name = "libz-sys"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "gcc 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "pkg-config 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -262,7 +262,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "memchr"
-version = "0.1.7"
+version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -273,18 +273,18 @@ name = "miniz-sys"
 version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "gcc 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "nom"
-version = "1.2.0"
+version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "num"
-version = "0.1.30"
+version = "0.1.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -293,12 +293,10 @@ dependencies = [
 
 [[package]]
 name = "num_cpus"
-version = "0.2.10"
+version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -309,13 +307,13 @@ dependencies = [
  "gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "libressl-pnacl-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "pkg-config 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "pkg-config"
-version = "0.3.6"
+version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -336,17 +334,18 @@ dependencies = [
 
 [[package]]
 name = "regex"
-version = "0.1.48"
+version = "0.1.55"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "aho-corasick 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aho-corasick 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.2.2"
+version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -356,10 +355,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "semver"
-version = "0.2.2"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "nom 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "nom 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -369,7 +368,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "tar"
-version = "0.4.3"
+version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -455,6 +454,11 @@ dependencies = [
  "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "utf8-ranges"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "uuid"
 version = "0.1.18"
index b350ba6efad3778011137531091153523bcfd837..0143b3904fbaed5d9f45a2f1224d1b3a38bdd445 100644 (file)
@@ -1,4 +1,5 @@
 use std::collections::{HashSet, HashMap};
+use std::env;
 use std::path::{Path, PathBuf};
 use std::str::{self, FromStr};
 use std::sync::Arc;
@@ -46,6 +47,7 @@ pub struct Context<'a, 'cfg: 'a> {
     target_info: TargetInfo,
     host_info: TargetInfo,
     profiles: &'a Profiles,
+    rustflags: Option<String>,
 }
 
 #[derive(Clone)]
@@ -78,6 +80,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
         let engine = build_config.exec_engine.as_ref().cloned().unwrap_or({
             Arc::new(Box::new(ProcessEngine))
         });
+        let rustflags = env::var("RUSTFLAGS").ok();
         Ok(Context {
             target_triple: target_triple,
             host: host,
@@ -97,6 +100,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
             build_scripts: HashMap::new(),
             build_explicit_deps: HashMap::new(),
             links: Links::new(),
+            rustflags: rustflags,
         })
     }
 
@@ -616,4 +620,45 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
         //       profile? How is this controlled at the CLI layer?
         &self.profiles.dev
     }
+
+    pub fn rustflags_args(&self, unit: &Unit) -> Vec<String> {
+        // We *want* to apply RUSTFLAGS only to builds for the
+        // requested target architecture, and not to things like build
+        // scripts and plugins, which may be for an entirely different
+        // architecture. Cargo's present architecture makes it quite
+        // hard to only apply flags to things that are not build
+        // scripts and plugins though, so we do something more hacky
+        // instead to avoid applying the same RUSTFLAGS to multiple targets
+        // arches:
+        //
+        // 1) If --target is not specified we just apply RUSTFLAGS to
+        // all builds; they are all going to have the same target.
+        //
+        // 2) If --target *is* specified then we only apply RUSTFLAGS
+        // to compilation units with the Target kind, which indicates
+        // it was chosen by the --target flag.
+        //
+        // This means that, e.g. even if the specified --target is the
+        // same as the host, build scripts in plugins won't get
+        // RUSTFLAGS.
+        let compiling_with_target = self.build_config.requested_target.is_some();
+        let is_target_kind = unit.kind == Kind::Target;
+        let use_rustflags = match (compiling_with_target, is_target_kind) {
+            (false, _) => true,
+            (true, true) => true,
+            (true, false) => false,
+        };
+
+        if !use_rustflags { return Vec::new(); }
+
+        let mut args = Vec::new();
+
+        if let Some(ref a) = self.rustflags {
+            for s in a.split(" ") {
+                args.push(s.to_owned());
+            }
+        }
+
+        args
+    }
 }
index dad110c208e64b93a7338d28cef0c799d30e5fd7..41bf139b06e30b794c4ae8e8e00b9454d648c7e4 100644 (file)
@@ -243,9 +243,9 @@ fn rustc(cx: &mut Context, unit: &Unit) -> CargoResult<Work> {
     let dep_info_loc = fingerprint::dep_info_loc(cx, unit);
     let cwd = cx.config.cwd().to_path_buf();
 
-    return Ok(Work::new(move |desc_tx| {
-        debug!("about to run: {}", rustc);
+    let rustflags = cx.rustflags_args(unit);
 
+    return Ok(Work::new(move |desc_tx| {
         // Only at runtime have we discovered what the extra -L and -l
         // arguments are for native libraries, so we process those here. We
         // also need to be sure to add any -L paths for our plugins to the
@@ -267,6 +267,9 @@ fn rustc(cx: &mut Context, unit: &Unit) -> CargoResult<Work> {
             }
         }
 
+        // Add the arguments from RUSTFLAGS
+        rustc.args(&rustflags);
+
         desc_tx.send(rustc.to_string()).ok();
         try!(exec_engine.exec(rustc).chain_error(|| {
             human(format!("Could not compile `{}`.", name))
index 731546e6372ea5cfb358a315cfa9f04d6bc7ad94..d51c51d783d346ba1607cee3c656234b3a1f14f5 100644 (file)
@@ -2068,3 +2068,331 @@ test!(manifest_with_bom_is_ok {
     assert_that(p.cargo_process("build").arg("-v"),
                 execs().with_status(0));
 });
+
+test!(rustflags_normal_source {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+        "#)
+        .file("src/lib.rs", "")
+        .file("src/bin/a.rs", "fn main() {}")
+        .file("examples/b.rs", "fn main() {}")
+        .file("tests/c.rs", "#[test] fn f() { }")
+        .file("benches/d.rs", r#"
+            #![feature(test)]
+            extern crate test;
+            #[bench] fn run1(_ben: &mut test::Bencher) { }"#);
+    p.build();
+
+    // Use RUSTFLAGS to pass an argument that will generate an error
+    assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
+                .arg("--lib"),
+                execs().with_status(101));
+    assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
+                .arg("--bin=a"),
+                execs().with_status(101));
+    assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
+                .arg("--bin=b"),
+                execs().with_status(101));
+    assert_that(p.cargo("check").env("RUSTFLAGS", "-Z bogus"),
+                execs().with_status(101));
+    assert_that(p.cargo("bench").env("RUSTFLAGS", "-Z bogus"),
+                execs().with_status(101));
+});
+
+test!(rustflags_build_script {
+    // RUSTFLAGS should be passed to rustc for build scripts
+    // when --target is not specified.
+    // In this test if --cfg foo is passed the build will fail.
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            build = "build.rs"
+        "#)
+        .file("src/lib.rs", "")
+        .file("build.rs", r#"
+            fn main() { }
+            #[cfg(not(foo))]
+            fn main() { }
+        "#);
+    p.build();
+
+    assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
+                execs().with_status(0));
+});
+
+test!(rustflags_build_script_dep {
+    // RUSTFLAGS should be passed to rustc for build scripts
+    // when --target is not specified.
+    // In this test if --cfg foo is not passed the build will fail.
+    let foo = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            build = "build.rs"
+
+            [build-dependencies.bar]
+            path = "../bar"
+        "#)
+        .file("src/lib.rs", "")
+        .file("build.rs", r#"
+            fn main() { }
+        "#);
+    let bar = project("bar")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "bar"
+            version = "0.0.1"
+        "#)
+        .file("src/lib.rs", r#"
+            fn bar() { }
+            #[cfg(not(foo))]
+            fn bar() { }
+        "#);
+    foo.build();
+    bar.build();
+
+    assert_that(foo.cargo("build").env("RUSTFLAGS", "--cfg foo"),
+                execs().with_status(0));
+});
+
+test!(rustflags_plugin {
+    // RUSTFLAGS should be passed to rustc for plugins
+    // when --target is not specified.
+    // In this test if --cfg foo is not passed the build will fail.
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+
+            [lib]
+            name = "foo"
+            plugin = true
+        "#)
+        .file("src/lib.rs", r#"
+            fn main() { }
+            #[cfg(not(foo))]
+            fn main() { }
+        "#);
+    p.build();
+
+    assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo"),
+                execs().with_status(0));
+});
+
+test!(rustflags_plugin_dep {
+    // RUSTFLAGS should be passed to rustc for plugins
+    // when --target is not specified.
+    // In this test if --cfg foo is not passed the build will fail.
+    let foo = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+
+            [lib]
+            name = "foo"
+            plugin = true
+
+            [dependencies.bar]
+            path = "../bar"
+        "#)
+        .file("src/lib.rs", r#"
+            fn foo() { }
+        "#);
+    let bar = project("bar")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "bar"
+            version = "0.0.1"
+
+            [lib]
+            name = "bar"
+        "#)
+        .file("src/lib.rs", r#"
+            fn bar() { }
+            #[cfg(not(foo))]
+            fn bar() { }
+        "#);
+    foo.build();
+    bar.build();
+
+    assert_that(foo.cargo("build").env("RUSTFLAGS", "--cfg foo"),
+                execs().with_status(0));
+});
+
+test!(rustflags_normal_source_with_target {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+        "#)
+        .file("src/lib.rs", "")
+        .file("src/bin/a.rs", "fn main() {}")
+        .file("examples/b.rs", "fn main() {}")
+        .file("tests/c.rs", "#[test] fn f() { }")
+        .file("benches/d.rs", r#"
+            #![feature(test)]
+            extern crate test;
+            #[bench] fn run1(_ben: &mut test::Bencher) { }"#);
+    p.build();
+
+    let ref host = ::rustc_host();
+
+    // Use RUSTFLAGS to pass an argument that will generate an error
+    assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
+                .arg("--lib").arg("--target").arg(host),
+                execs().with_status(101));
+    assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
+                .arg("--bin=a").arg("--target").arg(host),
+                execs().with_status(101));
+    assert_that(p.cargo("build").env("RUSTFLAGS", "-Z bogus")
+                .arg("--bin=b").arg("--target").arg(host),
+                execs().with_status(101));
+    assert_that(p.cargo("check").env("RUSTFLAGS", "-Z bogus")
+                .arg("--target").arg(host),
+                execs().with_status(101));
+    assert_that(p.cargo("bench").env("RUSTFLAGS", "-Z bogus")
+                .arg("--target").arg(host),
+                execs().with_status(101));
+});
+
+test!(rustflags_build_script_with_target {
+    // RUSTFLAGS should not be passed to rustc for build scripts
+    // when --target is specified.
+    // In this test if --cfg foo is passed the build will fail.
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            build = "build.rs"
+        "#)
+        .file("src/lib.rs", "")
+        .file("build.rs", r#"
+            fn main() { }
+            #[cfg(foo)]
+            fn main() { }
+        "#);
+    p.build();
+
+    let host = ::rustc_host();
+    assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo")
+                .arg("--target").arg(host),
+                execs().with_status(0));
+});
+
+test!(rustflags_build_script_dep_with_target {
+    // RUSTFLAGS should not be passed to rustc for build scripts
+    // when --target is specified.
+    // In this test if --cfg foo is passed the build will fail.
+    let foo = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            build = "build.rs"
+
+            [build-dependencies.bar]
+            path = "../bar"
+        "#)
+        .file("src/lib.rs", "")
+        .file("build.rs", r#"
+            fn main() { }
+        "#);
+    let bar = project("bar")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "bar"
+            version = "0.0.1"
+        "#)
+        .file("src/lib.rs", r#"
+            fn bar() { }
+            #[cfg(foo)]
+            fn bar() { }
+        "#);
+    foo.build();
+    bar.build();
+
+    let host = ::rustc_host();
+    assert_that(foo.cargo("build").env("RUSTFLAGS", "--cfg foo")
+                .arg("--target").arg(host),
+                execs().with_status(0));
+});
+
+test!(rustflags_plugin_with_target {
+    // RUSTFLAGS should not be passed to rustc for plugins
+    // when --target is specified.
+    // In this test if --cfg foo is passed the build will fail.
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+
+            [lib]
+            name = "foo"
+            plugin = true
+        "#)
+        .file("src/lib.rs", r#"
+            fn main() { }
+            #[cfg(foo)]
+            fn main() { }
+        "#);
+    p.build();
+
+    let host = ::rustc_host();
+    assert_that(p.cargo("build").env("RUSTFLAGS", "--cfg foo")
+                .arg("--target").arg(host),
+                execs().with_status(0));
+});
+
+test!(rustflags_plugin_dep_with_target {
+    // RUSTFLAGS should not be passed to rustc for plugins
+    // when --target is specified.
+    // In this test if --cfg foo is passed the build will fail.
+    let foo = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+
+            [lib]
+            name = "foo"
+            plugin = true
+
+            [dependencies.bar]
+            path = "../bar"
+        "#)
+        .file("src/lib.rs", r#"
+            fn foo() { }
+        "#);
+    let bar = project("bar")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "bar"
+            version = "0.0.1"
+
+            [lib]
+            name = "bar"
+        "#)
+        .file("src/lib.rs", r#"
+            fn bar() { }
+            #[cfg(foo)]
+            fn bar() { }
+        "#);
+    foo.build();
+    bar.build();
+
+    let host = ::rustc_host();
+    assert_that(foo.cargo("build").env("RUSTFLAGS", "--cfg foo")
+                .arg("--target").arg(host),
+                execs().with_status(0));
+});